package Classes
{
	import UIFree.uif_app;
	
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLRequest;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;

	public class CLoader extends Loader {
		private static var _dynamics: Object = {};
		private static var _dyninc: int = 0;
		private var _sourceUrl	: String;
		private var _loaded		: Boolean;
		private var _initRoot	: Object;
		public static const DYNAMIC: String = 'DYNAMIC';
		
		public static const SWFTYPE: String = 'application/x-shockwave-flash';
		public function CLoader(a_parent: Sprite=null, URL: String='', 
					a_onComplete: Function=null, a_x: Number=0, a_y:Number=0, context: LoaderContext=null) {
			super();
			if (a_parent) {
				a_parent.addChild(this);
			}// else _initRoot = uif_app.instance();
			_initRoot = uif_app.instance();
			_sourceUrl = '';
			x = a_x;
			y = a_y;
			
			contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, doError);
			contentLoaderInfo.addEventListener(Event.COMPLETE, doComplete);
/*			addEventListener(Event.REMOVED, function(e: Event): void {
				//doComplete(e);
				trace(e.target == parent);
			});*/
			
			if (URL) this.load(new URLRequest(URL), context);
			if (a_onComplete != null) {
				contentLoaderInfo.addEventListener(Event.COMPLETE, a_onComplete);
			}
		}
		
		public function get This(): CLoader {
			return this;
		}
		
		protected function get Root(): Object {
			return _initRoot;
		}
		
		protected function doComplete(e: Event): void {
			_loaded = true;
			Root.dispatchEvent(new GDataEvent(GDataEvent.RESPONSEIMAGE, this));
		}
		
		protected function doError(e: IOErrorEvent): void {
			Root.dispatchEvent(new GDataEvent(GDataEvent.IMAGELOADERROR, e.text));
			Root.dispatchEvent(new GDataEvent(GDataEvent.RESPONSEIMAGE, this));
		}
		
		override public function load(request:URLRequest, context:LoaderContext=null):void {
			if (loaded) unload();
			var di: int = request.url.indexOf(DYNAMIC);
			if (di > -1) {
				var dyindex: String = request.url.substr(di);
				var loader: CLoader = _dynamics[dyindex];
				if (loader != null) {
					loadBytes(loader.contentLoaderInfo.bytes);	
				}
			} else {
				if (GONFIG::foolingpolicy) { // Условная компиляция, переменная GONFIG::foolingpolicy задается в переменных компилятора строкой: -define+=GONFIG::foolingpolicy,true
					if (request.url.split('?')[0].indexOf('.swf') == -1) {
						var tmp: Loader = new Loader();	// Обходим политику
						function tmp_doComplete(e: Event): void {
							Root.dispatchEvent(new GDataEvent(GDataEvent.RESPONSEIMAGE, This));
							superloadBytes(tmp.contentLoaderInfo.bytes);
							tmp.contentLoaderInfo.removeEventListener(Event.COMPLETE, tmp_doComplete);
							tmp.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, doError);
							tmp.unload();
							_sourceUrl = request.url;
						}
						
						tmp.contentLoaderInfo.addEventListener(Event.COMPLETE, tmp_doComplete);
						tmp.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, doError);
						tmp.load(request, context);
						_sourceUrl = request.url;
						Root.dispatchEvent(new GDataEvent(GDataEvent.REQUESTIMAGE, This));
					} else {
						super.load(request, context);
						Root.dispatchEvent(new GDataEvent(GDataEvent.REQUESTIMAGE, This));
					}
				} else {
					super.load(request, context);
					Root.dispatchEvent(new GDataEvent(GDataEvent.REQUESTIMAGE, This));
				}
			}
		}
		
		private function superloadBytes(bytes:ByteArray, context:LoaderContext=null): void {
			if (loaded) unload();
			super.loadBytes(bytes, context);
		}
		
		override public function loadBytes(bytes:ByteArray, context:LoaderContext=null):void {
			_sourceUrl = DYNAMIC + _dyninc;
			_dyninc++;
			_dynamics[_sourceUrl] = this;
			superloadBytes(bytes, context);
		}
		
		public function get isDynamic(): Boolean {
			return _sourceUrl.indexOf(DYNAMIC) > -1;
		}
		
		public function dispose(): void {
			unload();
			if (parent) parent.removeChild(this);
			contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, doError);
			contentLoaderInfo.removeEventListener(Event.COMPLETE, doComplete);
		}
		
		override public function unload():void {
			if (isDynamic) delete(_dynamics[_sourceUrl]);
			_loaded = false;
			super.unload();
		}
		
		public function get sourceUrl(): String {
			return _sourceUrl?_sourceUrl:contentLoaderInfo.url;
		}
		
		public function get loaded(): Boolean {
			return _loaded;
		}
		
		public function duplicate(target: Loader=null): Loader {
			if (contentLoaderInfo.bytesLoaded > 0) { 
				if (!target) target = new CLoader();
				if (target is CLoader) {
					if (isDynamic) target.loadBytes(this.contentLoaderInfo.bytes);
					else {
						(target as CLoader).superloadBytes(contentLoaderInfo.bytes);
						(target as CLoader)._sourceUrl = _sourceUrl?_sourceUrl:contentLoaderInfo.url;
					}
				} else target.loadBytes(contentLoaderInfo.bytes);
				return target;
			} else return null;
		}
	}
}